<?php
// 开启严格模式
declare (strict_types = 1);

namespace app\home\controller;

// 引用tp的基础控制器
use app\BaseController;
use app\common\model\Post\Cate as CateModel;
use app\common\validate\User\User as UserValiDate;
// 引入tp的视图门面
use think\facade\View;
// 引用验证码类
use think\captcha\facade\Captcha;
use think\facade\Db;
use app\common\model\User\User as UserModel;
use app\common\model\Post\Post as PostModel;
use app\common\model\User\Record as RecordModel;
use app\common\validate\User\Record as RecordValiDate;
use think\exception\ValidateException;

class Index extends BaseController
{
    protected $middleware = [
        // except => 设置哪个方法不走中间件
    	\app\home\middleware\LoginAuth::class => ['except' 	=> ['index','login','register','vercode'] ],
    ];

    // 控制器初始化
    protected function initialize()
    {
        // 手动继承父级的控制器初始化
        parent::initialize();

        $this->UserModel = new UserModel();
        $this->RecordModel = new RecordModel();

        // 获取cookie
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'),true) : [];

        $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

        // 查询该用户是否存在数据库
        $user = $this->UserModel::find($userid);

        $data = [
            'id' => isset($user['id']) ? $user['id'] : '',
            'email' => isset($user['email']) ? $user['email'] : '',
            'nickname' => isset($user['nickname']) ? $user['nickname'] : '',
            'avatar' => isset($user['avatar']) ? $user['avatar'] : '',
            'sex' => isset($user['sex']) ? $user['sex'] : '',
            'province' => isset($user['province']) ? $user['province'] : '',
            'city' => isset($user['city']) ? $user['city'] : '',
            'district' => isset($user['district']) ? $user['district'] : '',
            'content' => isset($user['content']) ? $user['content'] : '',
            'point' => isset($user['point']) ? $user['point'] : '',
            'vip' => isset($user['vip']) ? $user['vip'] : '',
            'auth' => isset($user['auth']) ? $user['auth'] : '',
            'cover' => isset($user['cover']) ? $user['cover'] : '',
            'createtime' =>isset($user['createtime']) ? $user['createtime'] : '',
        ];

        $User = array_filter($data) ? $data : [];

        // 赋值给所有使用该中间件的视图
        if($User)
        {
            View::assign([
                'LoginUser' => $data
            ]);
        }else{
            View::assign([
                'LoginUser' => []
            ]);
        }

        $this->LoginUser = $data;

    }

    public function index()
    {
        // 接收分类id
        $cateid = $this->request->param('cateid',0);

         // 接收帖子状态
         $state = $this->request->param('state','');

         $accept = $this->request->param('accept','0');

         $keyword = $this->request->param('keyword','');
 
         // 定义条件数组
         $where = [];
 
         // 组装分类查询条件
         if($cateid)
         {
             $where[] = ['cateid','=',$cateid];
         }
 
 
         if($state || $state === '0')
         {
             $where[] = ['state','=',$state];
         }
 
         if($accept)
         {
             $where[] = ['accept','exp',Db::raw('IS NOT NULL')];
         }else{
             $where[] = ['accept','exp',Db::raw('IS NULL')];
         }

         if($keyword)
        {
            $where[] = ['title|content','like',"%$keyword%"];
        }
        // 查询分类所有的数据
        $CateList = CateModel::order('weigh','desc')->limit(6)->select();

        // 查询帖子数据
        $PostList = PostModel::with(['user'])->where($where)->order('createtime','desc')->paginate(['list_rows' => 2,'query' => $this->request->param()]);
        // var_dump($PostList);
        // exit;

        /* 
            每次签到成功都会自动新增一条消费记录

            每天 00：00 到 23：59

            查询消费记录是否有当前登录用户签到记录
        */

        $userid = isset($this->LoginUser['id']) ? $this->LoginUser['id'] : 0;

        $sign = RecordModel::whereDay('createtime')->where('userid',$userid)->where('state',4)->find();

        $SignPoint = Db::name('config')->where('key','SignPoint')->value('value');

        // 查询分类所有的数据
        $CateList = CateModel::order('weigh','desc')->limit(6)->select();

        // 查询帖子数据
        $PostList = PostModel::with(['user'])->where($where)->order('createtime','desc')->paginate(['list_rows' => 1,'query' => $this->request->param()]);

        /* 
            每次签到成功都会自动新增一条消费记录

            每天 00：00 到 23：59

            查询消费记录是否有当前登录用户签到记录
        */

        $userid = isset($this->LoginUser['id']) ? $this->LoginUser['id'] : 0;

        $sign = RecordModel::whereDay('createtime')->where('userid',$userid)->where('state',4)->find();

        $SignPoint = Db::name('config')->where('key','SignPoint')->value('value');


        // view视图助手函数
        /* 
            第一个参数 指定访问视图
            第二个参数 把控制器的变量赋值视图输出
        */
        // 使用tp提供门面的方法输出视图
        return View::fetch('',[
            'CateList' => $CateList,
            'cateid' => $cateid,
            'PostList' => $PostList,
            'state' => $state,
            'accept' => $accept,
            'keyword' => $keyword,
            'sign' => $sign,
            'SignPoint' => $SignPoint,
            'userid' => $userid
        ]);
        // return view();
    }

     // 签到
     public function sign()
    {
        
        if($this->request->isAjax())
        {
            $userid = $this->request->param('userid');

            $User = $this->UserModel->find($userid);

            if(!$User)
            {
                $this->error('非法登录');
            }

            $sign = RecordModel::where(['userid' => $userid,'state' => 4])->whereDay('createtime')->find();

            if($sign)
            {
                $this->error('你已签到了，无须重复签到');
            }

            // 获取签到积分
            $SignPoint = Db::name('config')->where('key','SignPoint')->value('value');

            /* 
                消费记录 新增签到
                用户 更新积分
            */

            UserModel::startTrans();
            RecordModel::startTrans();

            // 封装消费记录的数据
            $RecordData = [
                'content' => "您签到成功，获得了{$SignPoint}积分",
                'point' => $SignPoint,
                'state' => 4,
                'userid' => $userid
            ];
            
            try {
                validate(RecordValiDate::class)->check($RecordData);
            } catch (ValidateException $e) {
                $this->error($e->getMessage());
            }
            
            $RecordStatus = $this->RecordModel->save($RecordData);
            
            if($RecordStatus === FALSE)
            {
                $this->error('签到记录新增失败');
            }

            $User->point = bcadd((String)$User['point'],(String)$SignPoint);

            $UserStatus = $User->save();

            if($UserStatus === FALSE)
            {
                RecordModel::rollback();
                $this->error('用户积分更新失败');
            }

            if($UserStatus === FALSE || $RecordStatus === FALSE)
            {
                RecordModel::rollback();
                UserModel::rollback();
                $this->error('签到失败');
            }else{
                RecordModel::commit();
                UserModel::commit();
                $this->success('签到成功');
            }
        }
    }

    // 退出
    public function logout()
    {
        cookie('LoginUser',null);

        $this->success('退出成功',(String)url('/home/index/index'));
    }

    // 登录页面
    public function login()
    {
        // 获取cookie 
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'),true) : [];

        if($LoginUser)
        {
            $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

            $User = $this->UserModel->find($userid);

            if(!$User)
            {
                cookie('LoginUser',null);
                $this->error('非法登录',(String)url('/home/index/login'));
            }

            $this->success('你已登录了，无须重复登录',(String)url('/home/user/index'));
        }


        // 判断有没有POST请求
        if($this->request->isPost())
        {
            // 验证码 input => 全局函数 接收输入参数
            $vercode = input('vercode');

            if(!captcha_check($vercode))
            {
                $this->error('验证码错误，请重新输入');
            }

            // 接收全部参数
            $params = $this->request->param();

            // 静态方法 条件查询 where `email` = $params['email'] find = 查询单条
            $User = UserModel::where(['email' => $params['email']])->find();

            if(!$User)
            {
                $this->error('用户不存在，请重新输入');
            }

            $password = md5($params['pass'].$User['salt']);

            if($password != $User['password'])
            {
                $this->error('密码错误，请重新输入');
            }

            // 封装cookie数组
            $data = [
                'id' => $User['id'],
                'email' => $User['email'],
                'nickname' => $User['nickname'],
                'avatar' => $User['avatar'],
                'sex' => $User['sex'],
                'province' => $User['province'],
                'city' => $User['city'],
                'district' => $User['district'],
                'content' => $User['content'],
                'point' => $User['point'],
                'vip' => $User['vip'],
                'auth' => $User['auth'],
                'cover' => $User['cover'],
                'createtime' => $User['createtime'],
            ];
            
            // 转成json字符串
            $json = json_encode($data);

            // cookie 助手函数
            cookie('LoginUser',$json);

            $this->success('登录成功',(String)url('/home/user/index'));

        }
        return view();
    }

    // 注册页面
    public function register()
    {
        if($this->request->isPost())
        {
            // 接收验证码 接收POST类型
            // $vercode = $this->request->post('vercode','');
            $vercode = request()->param('vercode');

            if(!captcha_check($vercode))
            {
                $this->error('验证码错误，请重新输入');
            }

            // 接收全部参数
            $params = $this->request->param();

            // 判断密码与确认密码是否不一致
            if($params['pass'] != $params['repass'])
            {
                $this->error('密码与确认密码不一致，请重新输入');
            }

            // 生成密码盐
            $salt = build_ranstr();

            // 拼接 + md5加密
            $password = md5($params['pass'].$salt);

            // 当用户注册时，把注册积分给该用户
            $point = Db::name('config')->where('key','RegisterPoint')->value('value');

            // 封装数据
            $data = [
                'email' => $params['email'],
                'nickname' => $params['nickname'],
                'password' => $password,
                'salt' => $salt,
                'sex' => 0,
                'point' => $point,
                'vip' => 1,
                'auth' => 0
            ];

            // 验证数据是否正确
            try {
                // 用验证方法 第一个参数 需要验证数据 第二个 验证器
                $this->validate($data,UserValiDate::class);
            } catch (\think\exception\ValidateException $e) {
                // 把错误信息输出
                $this->error($e->getError());
            }

            // 实例化User模型
            $User = new UserModel();

            // save => 插入数据
            $result = $User->save($data);

            // 是否成功
            if($result === FALSE)
            {
                $this->error('注册失败');
            }else{
                $this->success('注册成功',(String)url('/home/index/login'));
            }
        }
        return view();
    }

    // 验证邮件
    public function email()
    {
        $email = $this->request->param('email');

        $User = $this->UserModel->column('id,email,salt');

        // 定义id
        $userid = 0;

        foreach($User as $item)
        {
            $Eamil = md5($item['email'].$item['salt']);

            if($email == $Eamil)
            {
                $userid = $item['id'];
                break;
            }
        }

        $user = $this->UserModel->find($userid);

        if(!$user)
        {
            $this->error('该邮箱不存在，请注册',(String)url('/home/index/register'));
        }

        $data = [
            'auth' => 1
        ];

        // 如果有主键就更新，没主键就是插入
        $result = $user->save($data);

        if($result === FALSE)
        {
            $this->error('认证失败',(String)url('/home/index/index'));
        }else{

            $User = $this->UserModel->find($userid);

            // 封装cookie数组
            $data = [
                'id' => $User['id'],
                'email' => $User['email'],
                'nickname' => $User['nickname'],
                'avatar' => $User['avatar'],
                'sex' => $User['sex'],
                'province' => $User['province'],
                'city' => $User['city'],
                'district' => $User['district'],
                'content' => $User['content'],
                'point' => $User['point'],
                'vip' => $User['vip'],
                'auth' => $User['auth'],
                'cover' => $User['cover'],
                'createtime' => $User['createtime'],
            ];
            
            // 转成json字符串
            $json = json_encode($data);

            // cookie 助手函数
            cookie('LoginUser',$json);

            $this->success('认证成功',(String)url('/home/user/index'));
        }
    }

    // 验证码配置
    public function vercode()
    {
        return Captcha::create('vercode');
    }
}
